#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

from enum import Enum
from common.logger_wins import Logger
from common.env_common import get_install_head_path, adaptation_win_path

log = Logger("sqlserver.log").get_logger()


class ParamConstant:
    # 输入参数文件目录
    PARAM_FILE_PATH = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/tmp/"
    # 输出结果文件目录
    RESULT_PATH = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/stmp/"
    # VDI工具部署路径
    VDI_TOOL_PATH = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/bin/backupAPI"
    # RPCTool路径
    RPC_TOOL = f"{adaptation_win_path()}/DataBackup/ProtectClient/Plugins/GeneralDBPlugin/bin/rpctool.bat"
    POWER_SHELL_PATH = 'C:/WINDOWS/system32/WindowsPowerShell/v1.0/powershell'


class JobData:
    PID = None


class RecoveryMode:
    SIMPLE = "SIMPLE"
    FULL = "FULL"


class SQLServerStrConstant:
    SQLSERVER = "sqlserver"
    SQLSERVER_DEFAULT_SERVICES = "mssqlserver"  # default
    VDI_BACKUP_SUCCESS = "BACKUP DATABASE successfully"
    END_POINT = 5022
    SYS_DATABASE = ("master", "msdb", "tempdb", "model")
    DEFAULT_CHANNEL = 12
    # 当抛出以下错误，需要调低channel
    VDI_CHANNEL_ERROR_CODE = ("80770009", "8077000a", "80770004", "80770003")
    DEFAULT_INSTANCE_NAME = "MSSQLSERVER"


class SQLServerType:
    SQL_SERVER_INSTANCE = "SQLServer-instance"
    SQL_SERVER_DATABASE = "SQLServer-database"
    SQL_SERVER_CLUSTER_INSTANCE = "SQLServer-clusterInstance"
    SQL_SERVER_ALWAYS_ON = "SQLServer-alwaysOn"


class SQLServerJsonConstant:
    EXTEND_INFO = "extendInfo"
    CLUSTER_TYPE = "clusterType"
    JOB = "job"
    PROTECT_OBJECT = "protectObject"
    SUBTYPE = "subType"
    APP_ENV = "protectEnv"
    ENDPOINT = "endpoint"
    AUTH = "auth"
    AUTH_TYPE = "authType"
    INSTANCE_PORT = "instancePort"
    NODES = "nodes"
    REPOSITORIES = "repositories"
    REPOSITORY_TYPE = "repositoryType"
    PATH = "path"
    BACK_JOB_RESULT = "backupJobResult"
    COPY = "copies"
    TIMESTAMP = "timestamp"
    BACKUP_TIME = "backupTime"
    BACKUP_LIMIT = "BackupLimit"
    NAME = "name"
    JOB_PARAM = "jobParam"
    BACKUP_TYPE = "backupType"
    INSTANCE_NAME = "parentName"
    RESTORE_TYPE = "restoreType"
    TARGET_ENV = "targetEnv"
    TARGET_OBJECT = "targetObject"
    NEW_NAME = "newDatabaseName"
    NEW_PATH = "newDatabasePath"
    TYPE = "type"
    REMOTE_PATH = "remote_path"
    ID = "id"
    RESTORE_TIME_STAMP = "restoreTimestamp"
    RESTORE_INSTANCE = "instance"


class ExecCmdResult:
    SUCCESS = "0"
    UNKNOWN_CMD = "127"
    RE_TRY_NUM = 10


class BodyErr(Enum):
    ERR_PLUGIN_CANNOT_BACKUP = 0x64032B0C  # 1677929228
    ERR_INC_TO_FULL = 0x5E02502D  # 1577209901
    ERROR_COMMON_INVALID_PARAMETER = 0x5F025102
    SQLSERVER_REGISTER_TYPE_ERROR = 0x5E0250D4  # 1577210068
    SQLSERVER_AUTH_INFO_ERROR = 0x5E0250D6  # 1577210070
    ERROR_INTERNAL = 0x5F025101  # 1593987329
    RESTORE_FAIL_FOR_DATABASE_EXIST = 0x5E0250E7  # 1577210087
    RESTORE_FAIL_FOR_DATABASE_FILE_EXIST = 0x5E0250E8  # 1577210088
    RESTORE_FAIL_FOR_ALWAYSON_EXIST = 0x5E0250E9  # 1577210089
    RESTORE_FAIL_FOR_VERSION_INCONSISTENCY = 0x5E0250EA  # 1577210090
    RESTORE_FAIL_FOR_NODE_NOT_MEET = 0x5E0250EB  # 1577210091
    RESTORE_FAIL_FOR_PATH_NOT_EXIST = 0x5E0250EC  # 1577210092
    RESTORE_FAIL_FOR_DATABASE_ERR_STATUS = 0x5E025E6A  # 1577213546
    BACKUP_FAIL_FOR_FULL_BACKUP_NEED = 0x5E0250F0  # 1577210096
    SQLSERVER_DATABASE_IN_USE_ERROR = 0x5E0250F1  # 1577210097
    SQLSERVER_REVERTIVE_MODE_ERROR = 0x5E0250DA  # 1577210074
    SQLSERVER_PERMISSIONS_ERROR = 0x5E0250DB  # 1577210075
    BACKUP_FAIL_FOR_DATABASE_STATE_ABNORMAL = 0x5E0250EF
    BACKUP_FAIL_FOR_LAST_LOG_FAIL = 0x5E0250DE
    SQLSERVER_DATABASE_NAME_INVALID = 0x5E0250F6
    SQLSERVER_DATABASE_NOT_EXISTS = 1577213539
    INSTANCE_STATE_ABNORMAL = 0x5E025E16
    NO_WINDOWS_POWER_SHELL_PERMISSION = 0x5E025E61
    ADJUST_CHANNELS = 1577213566
    ALWAYS_ON_GROUP_NO_DATABASE = 1577213567


class SQLServerCode(Enum):
    SUCCESS = 0
    FAILED = 200


class SQLServerProgressFileType:
    COMMON = "common"
    ABORT = "abort"
    INSTANCE_FULL_BACKUP = "instance_full_backup"
    INSTANCE_INC_BACKUP = "instance_inc_backup"
    LAST_LOG_BACKUP_STATUS = "LastLogBackupStatusFile"
    COPY_INFO_PARAM = "copyInfoParam"
    COPY_INFO = "copyInfo"
    REPORT_PROGRESS_PARAM = "ReportJobProgressParam"
    REPORT_JOB_PROGRESS = "ReportJobProgress"


class VDIActionType(int, Enum):
    FULL_BACKUP = 1
    DIFF_BACKUP = 2
    LOG_BACKUP = 3
    LOG_BACKUP_TAIL = 4
    FULL_RESTORE_WITH_REPLACE = 5  # 全量恢复，WITH REPLACE
    LOG_RESTORE_WITH_NO_RECOVERY = 6  # 日志的差异恢复，WITH NORECOVERY
    DIFF_RESTORE_WITH_NO_RECOVERY_REPLACE = 7  # 差异/日志的全量恢复，WITH REPLACE NORECOVERY
    DIFF_RESTORE_WITH_RECOVERY = 8  # 差异恢复， WITH RECOVERY
    POINT_IN_TIME_RESTORE_WITH_NO_RECOVERY = 9
    POINT_IN_TIME_RESTORE_WITH_RECOVERY = 10


class DatabaseRecoveryModel(str, Enum):
    # sqlsever恢复模式
    SIMPLE = "SIMPLE"
    FULL = "FULL"
    BULK_LOGGED = "BULK_LOGGED"


class SQLTmpFileName:
    # sqlserver临时文件名
    QUERY_BACKUP_SET_SQL = "QueryBackupSet.sql"  # 查询备份集命令文件
    OUTPUT_BACKUP_SET = "QueryBackupSet.out"  # 备份集查询结果
    COPY_INFO_FILE = "CopyInfoFile"  # 副本信息
    QUERY_PROGRESS_SQL = "QueryProgress.sql"  # 查询备份进度命令文件
    DATABASE_PROGRESS_FILE = "QueryProgress.out"  # 查询进度结果文件


class ProgressConst(int, Enum):
    MIN_PROGRESS = 5
    INSTANCE_MAX_PROGRESS = 90
    DATABASE_MAX_PROGRESS = 95
    PROGRESS_ONE_HUNDRED = 100


class RestoreTypeEnum(int, Enum):
    FULL_RESTORE = 1
    DIFF_RESTORE = 2
    POINT_IN_TIME_RESTORE = 3


class RestoreSubJobName:
    CHECK_JOB = "check"
    PRIMARY_JOB = "primary"
    SECONDARY_JOB = "secondary"


class MasterRestoreStup:
    FIRST_STEP = "net stop mssqlserver /y"
    SECOND_STEP = "net start mssqlserver /m"
    THIRD_STEP = "net stop mssqlserver"
    FOURTH_STEP = "net start mssqlserver"


class SqlCmd:
    EXECUTION_POLICY = "Get-ExecutionPolicy"
    CLUSTER_INFO = "Get-Cluster"
    CLUSTER_NODE = "Get-ClusterNode"
    FIND_ALL_RESOURCE = "Get-ClusterResource"
    SUSPEND_RESOURCE = "Suspend-CLusterResource"
    RESUME_RESOURCE = "Resume-ClusterResource"
    START_RESOURCE = "Start-ClusterResource"
    FIND_INSTANCE_NAME = "SELECT @@SERVICENAME, @@SERVERNAME\ngo\nexit()\ngo\n"
    AUTH_CMD = "exit()\ngo\n"
    FIND_AG_DEPENDS = "select T1.ag_name, T1.ag_id, T.ag_resource_id, " \
                      "T.node_name from sys.dm_hadr_instance_node_map T " \
                      "left join sys.dm_hadr_name_id_map T1 on " \
                      "T1.ag_resource_id = T.ag_resource_id"
    ORDER_DATABASES = "select name, sum(size) as total_size from " \
                      "(select t1.name, t2.size from sys.databases t1 " \
                      "left join sys.master_files t2 on t1.database_id = t2.database_id " \
                      "where t2.type = 0 and t2.state = 0) as t3 group by name order by total_size asc;"


class RegCmd:
    FIND_CLUSTER_NAME = "REG QUERY \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \
                        "Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\Cluster\" /v ClusterName"
    FIND_INSTANCE_NAME = "REG QUERY \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SQL Server\"" \
                         " /v InstalledInstances"
    FIND_INSTANCE_VERSION = "REG QUERY \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \
                            "Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQLServer\\" \
                            "CurrentVersion\" /v CurrentVersion"


class JobType(str, Enum):
    BACKUP = "BACKUP DATABASE"
    RESTORE = "RESTORE DATABASE"


class Progress:
    PROGRESS = 5
    START_PROGRESS = 15
    MAX_PROGRESS = 90
    PROGRESS_ONE_HUNDRED = 100
    INTERVAL_PROGRESS = 0


class SqlSystemId:
    MIN_ID = 5


class TmpFile:
    EXIT_FILE = f"{get_install_head_path()}" \
                "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\exitSql.Sql"
    OUT_FILE = f"{get_install_head_path()}" \
               "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\out.txt"
    LIST_FILE = f"{get_install_head_path()}" \
                "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\listResource.sql"
    AG_LIST_FILE = f"{get_install_head_path()}" \
                   "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\agList.sql"
    RESOURCE_FILE = f"{get_install_head_path()}" \
                    "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\tmpResource.sql"
    TMPRESOURCE_FILE = f"{get_install_head_path()}" \
                       "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\tmpResource.sql"
    TMPSQL_FILE = f"{get_install_head_path()}" \
                  "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\tempSql.sql"
    TMPSQLV1_FILE = f"{get_install_head_path()}" \
                    "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\temp1.sql"
    NODE_INFO_FILE = f"{get_install_head_path()}" \
                     "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\nodeInfo"
    INSTANCE_LIST_OUT = f"{get_install_head_path()}" \
                        "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\instanceList"
    SIMPLE_LIST_OUT = f"{get_install_head_path()}" \
                      "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\simpleList"
    ABNORMAL_LIST_OUT = f"{get_install_head_path()}" \
                        "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\abnormalList"
    AG_LIST_OUT = f"{get_install_head_path()}" \
                  "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\agInfo"
    AG_DATABASE_OUT = f"{get_install_head_path()}" \
                      "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\agDatabaseInfo"
    GROUP_INFO = f"{get_install_head_path()}" \
                 "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\agGroupInfo"
    ENDPOINT_INFO = f"{get_install_head_path()}" \
                    "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\agEndpointInfo"
    REPLICA_INFO = f"{get_install_head_path()}" \
                   "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\ReplicaInfo"
    AG_REPLICA_INFO = f"{get_install_head_path()}" \
                      "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\agReplicaInfo"
    DB_FILE_INFO = f"{get_install_head_path()}" \
                   "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\databaseFileInfo"
    DB_STATE_INFO = f"{get_install_head_path()}" \
                    "\\DataBackup\\ProtectClient\\Plugins\\GeneralDBPlugin\\stmp\\databaseStateInfo"


class SqlServerNameConst:
    MASTER = "master"
    REPORTSERVER = "ReportServer"
    TEMPDB = "tempdb"


class SqlSeverErrorKeyword:
    INUSE = "in use"


class SqlServerDefaultUser:
    DEFAULTUSER = "SYSTEM"


class SqlServerReportLabel:
    # 子任务（{0}）备份成功，共备份数据库数量：{1}
    BACKUP_SUB_JOB_SUCCESS_LABEL = "sqlserver_plugin_database_backup_subjob_success_label"
    # 子任务（{0}）正在备份中，待备份数据库数量：{1}，已备份数据库数量：{2}
    BACKUP_SUB_JOB_RUNNING_LABEL = "sqlserver_plugin_execute_backup_subjob_label"
    # 子任务（{0}）恢复成功，共恢复数据库数量：{1}。
    RESTORE_SUB_JOB_SUCCESS_LABEL = "sqlserver_plugin_database_restore_subjob_success_label"
    # 子任务（{0}）正在恢复中，待恢复数据库数量：{1}，已恢复数据库数量：{2}
    RESTORE_SUB_JOB_RUNNING_LABEL = "sqlserver_plugin_execute_restore_subjob_label"
    # 子任务（{0}）执行失败
    SUB_JOB_FAILED_LABEL = "plugin_task_subjob_fail_label"
    # 子任务（{0}）执行成功
    SUB_JOB_SUCCESS_LABEL = "plugin_task_subjob_success_label"
    # 全量备份副本（{0}）与数据库中最新的全量备份副本不一致，此次任务转为全量备份。
    SWITCH_TO_FULL_BACKUP_LABEL = "sqlserver_plugin_diff_backup_to_full_warn_label"


class SubJobExecResult:
    SUCCESS_NUM = 0


class CodeIdConst:
    # 适配中文系统
    WINDOWS_CODE = "65001"
    CONSTANT_129 = 129  # 空格个数
    TIMEOUT = 30  # sqlcmd超时时间
